package com.fun_ordering.controller;


import com.fun_ordering.components.NotifyRes;
import com.fun_ordering.service.FoOrderService;
import com.wechat.pay.java.core.Config;
import com.wechat.pay.java.core.exception.ValidationException;
import com.wechat.pay.java.core.notification.NotificationConfig;
import com.wechat.pay.java.core.notification.NotificationParser;
import com.wechat.pay.java.core.notification.RequestParam;
import com.wechat.pay.java.service.payments.model.Transaction;
import com.wechat.pay.java.service.refund.model.RefundNotification;
import com.wechat.pay.java.service.refund.model.Status;
import org.json.JSONException;
import org.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;


import javax.servlet.http.HttpServletRequest;
import java.io.BufferedReader;
import java.io.IOException;
import java.util.concurrent.TimeUnit;

@RestController
@RequestMapping("/pay")
public class WeiXinPayController {

    @Autowired
    private Config propConfig;

    @Autowired
    private FoOrderService foOrderService;

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    /**
     * 支付通知
     * @param request
     * @return
     */
    @PostMapping("/callback")
    public NotifyRes handlePaymentCallback(HttpServletRequest request) {

        // 获取Wechatpay-Signature
        String wechatpaySignature = request.getHeader("Wechatpay-Signature");
        // 获取Wechatpay-Serial
        String wechatpaySerial = request.getHeader("Wechatpay-Serial");
        // 获取Wechatpay-Nonce
        String wechatpayNonce = request.getHeader("Wechatpay-Nonce");
        // 获取Wechatpay-Timestamp
        String wechatpayTimestamp = request.getHeader("Wechatpay-Timestamp");
        // 获取Wechatpay-Signature-Type
        //String wechatpaySignatureType = request.getHeader("Wechatpay-Signature-Type");

        // 获取原始的请求体
        StringBuilder sb = new StringBuilder();
        String line;
        try (BufferedReader reader = request.getReader()) {
            while ((line = reader.readLine()) != null) {
                sb.append(line);
            }
        } catch (IOException e) {
            // 处理异常
            System.out.println("支付回调错误！！！！！！！！！！");
        }

        String originalRequestBody = sb.toString();
        // 然后将解码后的字符串转换为JSONObject
        JSONObject jsonObject = null;
        // 获取指定名称的参数值
        String payNotify = null;
        try {
            jsonObject = new JSONObject(originalRequestBody);
            payNotify = jsonObject.getString("id");
        } catch (JSONException e) {
            e.printStackTrace();
        }

        // 获取当前对象的锁
        synchronized (this) {
            // 进行状态检查和处理
            String notify = stringRedisTemplate.opsForValue().get("payNotify:" + payNotify);
            if(payNotify != null && payNotify.equals(notify)){
                return NotifyRes.success();
            }
        }

        // 构造 RequestParam
        RequestParam requestParam = new RequestParam.Builder()
                .serialNumber(wechatpaySerial)
                .nonce(wechatpayNonce)
                .signature(wechatpaySignature)
                .timestamp(wechatpayTimestamp)
                .body(originalRequestBody)
                .build();

        // 初始化 NotificationConfig
        NotificationConfig config = (NotificationConfig)propConfig;

        // 初始化 NotificationParser
        NotificationParser parser = new NotificationParser(config);

        try {
            // 以支付通知回调为例，验签、解密并转换成 Transaction
            Transaction transaction = parser.parse(requestParam, Transaction.class);
            // 根据支付结果进行后续业务处理
            if(transaction.getTradeState() == Transaction.TradeStateEnum.SUCCESS){
                //修改订单状态
                foOrderService.payAlready(Integer.valueOf(transaction.getOutTradeNo())); //商户订单号
                if(payNotify!=null){
                    stringRedisTemplate.opsForValue().set("payNotify:"+payNotify,payNotify,30, TimeUnit.SECONDS); //30s过期
                }
                return NotifyRes.success();
            }
        } catch (ValidationException e) {
            // 签名验证失败
            return NotifyRes.fail();
        }
        return null;
    }

    /**
     * 退款通知
     * @param request
     * @return
     */
    @PostMapping("/refundComplete")
    public NotifyRes handleRefundCallback(HttpServletRequest request){

        // 获取Wechatpay-Signature
        String wechatpaySignature = request.getHeader("Wechatpay-Signature");
        // 获取Wechatpay-Serial
        String wechatpaySerial = request.getHeader("Wechatpay-Serial");
        // 获取Wechatpay-Nonce
        String wechatpayNonce = request.getHeader("Wechatpay-Nonce");
        // 获取Wechatpay-Timestamp
        String wechatpayTimestamp = request.getHeader("Wechatpay-Timestamp");
        // 获取Wechatpay-Signature-Type
        //String wechatpaySignatureType = request.getHeader("Wechatpay-Signature-Type");

        // 获取原始的请求体
        StringBuilder sb = new StringBuilder();
        String line;
        try (BufferedReader reader = request.getReader()) {
            while ((line = reader.readLine()) != null) {
                sb.append(line);
            }
        } catch (IOException e) {
            // 处理异常
            System.out.println("退款回调错误！！！！！！！！！！");
        }
        String originalRequestBody = sb.toString();
        // 然后将解码后的字符串转换为JSONObject
        JSONObject jsonObject = null;
        // 获取指定名称的参数值
        String refundNotify = null;
        try {
            jsonObject = new JSONObject(originalRequestBody);
            refundNotify = jsonObject.getString("id");
        } catch (JSONException e) {
            e.printStackTrace();
        }

        // 获取当前对象的锁
        synchronized (this) {
            // 进行状态检查和处理
            String notify = stringRedisTemplate.opsForValue().get("refundNotify:" + refundNotify);
            if(refundNotify != null && refundNotify.equals(notify)){
                return NotifyRes.success();
            }
        }
        // 构造 RequestParam
        RequestParam requestParam = new RequestParam.Builder()
                .serialNumber(wechatpaySerial)
                .nonce(wechatpayNonce)
                .signature(wechatpaySignature)
                .timestamp(wechatpayTimestamp)
                .body(originalRequestBody)
                .build();

        // 初始化 NotificationConfig
        NotificationConfig config = (NotificationConfig)propConfig;
        // 初始化 NotificationParser
        NotificationParser parser = new NotificationParser(config);

        try {
            // 验签、解密并转换成 RefundNotification
            RefundNotification refundNotification = parser.parse(requestParam, RefundNotification.class);
            // 根据结果进行后续业务处理
            if(refundNotification.getRefundStatus()== Status.SUCCESS){
                //修改支付状态  退款成功
                foOrderService.refundAlready(Integer.valueOf(refundNotification.getOutTradeNo()));
                if(refundNotify!=null){
                    stringRedisTemplate.opsForValue().set("refundNotify:"+refundNotify,refundNotify,30, TimeUnit.SECONDS); //30s过期
                }
                return NotifyRes.success();
            }
        } catch (ValidationException e) {
            // 签名验证失败
            return NotifyRes.fail();
        }
        return null;
    }
}